local skynet 		= require "skynet"
local gateserver 	= require "snax.gateserver"
local netpack 		= require "skynet.netpack"
local show        	= require "showmsg" 
local forward		= require "forward"

local forward_if = false 
local watchdog
local connection = {}	
local forwarding = {}	

-- 注册个消息  
skynet.register_protocol {
	name = "client",
	id = skynet.PTYPE_CLIENT,
}


local handler = {}

-- 打开监听端口之前做些相关的初始化
function handler.open(source, conf)

	watchdog = conf.watchdog or source
end

-- 接收到客户端的数据
function handler.message(fd, msg, sz)
	-- recv a package, forward it
	local c = connection[fd]

	if c and forward_if and c.agent then 
	
		if forward:agent(c.agent, c.client, msg, sz) then 
			show:debug("网关message接收到无效值或空值 转发->agent 失败")
		end 

	elseif c then 

		if forward:message(watchdog,"socket","forward", fd, msg, sz) then 

			-- 默认不处理 直接忽略
			show:debug("网关message接收到无效值或空值 转发->forward 失败")
		end 
	else 

		if forward:message(watchdog, "socket", "data", fd, netpack.tostring(msg,sz), sz) then 
			show:debug("网关message接收到无效值或空值 转发-> data 失败")
		end 
	end 

--[[
	if c then 
		skynet.send(watchdog, "lua","socket","forward", fd, msg, sz)
	else 
		skynet.send(watchdog, "lua", "socket", "data", fd, netpack.tostring(msg, sz))
	end 


	
	local agent = c.agent
	if agent then
		--skynet.send(agent, "lua", "data", msg, sz)
		skynet.redirect(agent, c.client, "client", 1, msg, sz)
	else
		-- 非法的消息不做处理
		skynet.send(watchdog, "lua", "socket", "data", fd, netpack.tostring(msg, sz))
	end
]]--

end


-- 客户端连接
function handler.connect(fd, addr)

	local c = {
		fd = fd,
		ip = addr,
	}
	connection[fd] = c
	
	-- 转发到对应的函数上处理
	if forward:open(watchdog, fd, addr) then 

		show:debug("网关connect接收到 fd 或 addr 是空值或者是非法消息，默认忽略不做其他处理")
	end 


	--skynet.send(watchdog, "lua", "socket", "open", fd, addr)
end


-- 清除记录
local function unforward(c)
	if c.agent then
		forwarding[c.agent] = nil
		c.agent = nil
		c.client = nil
	end
end

--  关闭套接字
local function close_fd(fd)
	local c = connection[fd]
	if c then
		unforward(c)
		connection[fd] = nil
	end
end

-- 客户端断开连接
function handler.disconnect(fd)
	close_fd(fd)
	skynet.send(watchdog, "lua", "socket", "close", fd)
end

-- 当发生错误时 关闭fd
function handler.error(fd, msg)
	close_fd(fd)
	skynet.send(watchdog, "lua", "socket", "error", fd, msg)
end

-- 警告消息
function handler.warning(fd, size)
	skynet.send(watchdog, "lua", "socket", "warning", fd, size)
end

local CMD = {}

-- 转发条件 为真则转发到 agent 处理
function CMD.forward_switch()

	forward_if = true
end 

-- 允许fd接收数据  (一开始fd是不能接收数据， 这样做目的使fd控制权可以转让出去)
function CMD.forward(source, fd, client, address)

	local c = assert(connection[fd])
	unforward(c)
	c.client = client or 0
	c.agent = address or source
	forwarding[c.agent] = c
	gateserver.openclient(fd)
end


function CMD.accept(source, fd)
	local c = assert(connection[fd])
	unforward(c)
	gateserver.openclient(fd)
end

-- 关闭客户端连接
function CMD.kick(source, fd)
	gateserver.closeclient(fd)
end

-- gate 内部消息处理
function handler.command(cmd, source, ...)
	local f = assert(CMD[cmd])
	return f(source, ...)
end

gateserver.start(handler)
